<!DOCTYPE html>












  


<html class="theme-next pisces use-motion" lang="zh-CN">
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
























<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2">

<link rel="stylesheet" href="/css/main.css?v=7.1.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=7.1.0">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/logo1.jpg?v=7.1.0">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/logo1.jpg?v=7.1.0">


  <link rel="mask-icon" href="/images/logo.svg?v=7.1.0" color="#222">







<script id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Pisces',
    version: '7.1.0',
    sidebar: {"position":"left","display":"post","offset":12,"onmobile":false,"dimmer":false},
    back2top: true,
    back2top_sidebar: false,
    fancybox: false,
    fastclick: false,
    lazyload: false,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>


  




  <meta name="description" content="golang一见倾心，再见如故">
<meta name="keywords" content="Go">
<meta property="og:type" content="article">
<meta property="og:title" content="初探Go">
<meta property="og:url" content="https://luoo.oschina.io/2017/09/03/tech/初探Go/index.html">
<meta property="og:site_name" content="从你的全世界路过">
<meta property="og:description" content="golang一见倾心，再见如故">
<meta property="og:locale" content="zh-CN">
<meta property="og:updated_time" content="2019-04-14T12:28:00.723Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="初探Go">
<meta name="twitter:description" content="golang一见倾心，再见如故">



  <link rel="alternate" href="/atom.xml" title="从你的全世界路过" type="application/atom+xml">



  
  
  <link rel="canonical" href="https://luoo.oschina.io/2017/09/03/tech/初探Go/">



<script id="page.configurations">
  CONFIG.page = {
    sidebar: "",
  };
</script>

  <title>初探Go | 从你的全世界路过</title>
  












  <noscript>
  <style>
  .use-motion .motion-element,
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-title { opacity: initial; }

  .use-motion .logo,
  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">从你的全世界路过</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
    
      
        <p class="site-subtitle">心智渐开，世事渐杂</p>
      
    
    
  </div>

  <div class="site-nav-toggle">
    <button aria-label="切换导航栏">
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>



<nav class="site-nav">
  
    <ul id="menu" class="menu">
      
        
        
        
          
          <li class="menu-item menu-item-home">

    
    
    
      
    

    

    <a href="/" rel="section"><i class="menu-item-icon fa fa-fw fa-home"></i> <br>首页</a>

  </li>
        
        
        
          
          <li class="menu-item menu-item-categories">

    
    
    
      
    

    

    <a href="/categories/" rel="section"><i class="menu-item-icon fa fa-fw fa-th"></i> <br>分类</a>

  </li>
        
        
        
          
          <li class="menu-item menu-item-tags">

    
    
    
      
    

    

    <a href="/tags/" rel="section"><i class="menu-item-icon fa fa-fw fa-tags"></i> <br>标签</a>

  </li>
        
        
        
          
          <li class="menu-item menu-item-archives">

    
    
    
      
    

    

    <a href="/archives/" rel="section"><i class="menu-item-icon fa fa-fw fa-archive"></i> <br>归档</a>

  </li>
        
        
        
          
          <li class="menu-item menu-item-schedule">

    
    
    
      
    

    

    <a href="/schedule/" rel="section"><i class="menu-item-icon fa fa-fw fa-calendar"></i> <br>计划</a>

  </li>
        
        
        
          
          <li class="menu-item menu-item-you">

    
    
    
      
    

    

    <a href="/you/" rel="section"><i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br>知遇</a>

  </li>
        
        
        
          
          <li class="menu-item menu-item-about">

    
    
    
      
    

    

    <a href="/about/" rel="section"><i class="menu-item-icon fa fa-fw fa-user"></i> <br>关于</a>

  </li>

      
      
    </ul>
  

  

  
</nav>



  



</div>
    </header>

    


    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          
            

          
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://luoo.oschina.io/2017/09/03/tech/初探Go/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="方林">
      <meta itemprop="description" content="愿你出走半生，归来仍是少年">
      <meta itemprop="image" content="/images/logo1.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="从你的全世界路过">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">初探Go

              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">

            
            
            

            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              

              
                
              

              <time title="创建时间：2017-09-03 17:30:25" itemprop="dateCreated datePublished" datetime="2017-09-03T17:30:25+08:00">2017-09-03</time>
            

            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/编程技术/" itemprop="url" rel="index"><span itemprop="name">编程技术</span></a></span>

                
                
              
            </span>
          

          
            
            
              
              <span class="post-comments-count">
                <span class="post-meta-divider">|</span>
                <span class="post-meta-item-icon">
                  <i class="fa fa-comment-o"></i>
                </span>
            
                <span class="post-meta-item-text">评论数：</span>
                <a href="/2017/09/03/tech/初探Go/#comments" itemprop="discussionUrl">
                  <span class="post-comments-count valine-comment-count" data-xid="/2017/09/03/tech/初探Go/" itemprop="commentCount"></span>
                </a>
              </span>
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>golang<br>一见倾心，再见如故</p>
<a id="more"></a>
<style>
table th:first-of-type {
    width: 70px;
}
th:nth-of-type(2) {
    width: 500px;
}
</style>

<h2 id="环境变量"><a href="#环境变量" class="headerlink" title="环境变量"></a>环境变量</h2><h3 id="GOROOT"><a href="#GOROOT" class="headerlink" title="GOROOT"></a>GOROOT</h3><p>Go语言的当前安装目录</p>
<h3 id="GOPATH"><a href="#GOPATH" class="headerlink" title="GOPATH"></a>GOPATH</h3><p>Go语言的工作区的集合（意味着可以有很多个），工作区类似与工作目录。<br>工作区是放置Go源码文件的目录，一般情况下，Go源码文件都会存放在工作区中。工作区一般包含3个文件夹bin、pkg和src。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">/home/work/gocode</span><br><span class="line">|-bin</span><br><span class="line">|-pkg</span><br><span class="line">|-src</span><br></pre></td></tr></table></figure></p>
<p>IDE新建Go项目，IDE会自动执行<code>go get</code>命令把相应的基础包拉过来，这个过程中会新建bin、pkg和src目录。<br><code>bin</code>目录存放的是通过<code>go install</code>命令安装后，由Go命令原发文件生成的可执行文件。</p>
<blockquote>
<p><strong>注意</strong>：有两种情况，bin目录会变得没有意义。 1. 设置了有效的GOBIN环境变量；2. GOPATH包含多个工作区路径，必须设置GOBIN环境变量；</p>
</blockquote>
<p><code>pkg</code>目录存放通过<code>go isntall</code>命令安装后的代码包的归档文件（.a文件）。归档文件的名字就是代码包的名字。所有的归档文件都会被存放到该目录下的平台相关目录中，即<code>$GOPATH/pkg/$GOOS_$GOARCH</code>中，同样以代码包为组织形式。<br><code>$GOOS</code>和<code>$GOARCH</code>是不需要手动设置，是系统默认的。<code>$GOOS</code>是操作系统类型，<code>$GOARCH</code>是计算机架构。（譬如Mac平台是darwin_amd64）<br><code>src</code>目录存放以代码包组织形式的Go源码文件，每个代码包和<code>src</code>目录下的文件夹一一对应，每个子目录都是一个代码包。</p>
<blockquote>
<p><strong>注意</strong>：代码包包名和文件目录名，不严格要求一致（譬如文件目录叫<code>mypackage</code>，代码包包名声明为<code>package serveric</code>）。但是同一个目录下的源码文件第一行声明的所属包必须一致。</p>
</blockquote>
<p>Go源码文件分为以下几类：</p>
<ul>
<li>命令源码文件<br>命令源码文件是Go程序的入口。同一个代码包中最好不要放多个命令源码文件。多个命令源码文件虽然可以单独使用<code>go run</code>运行起来，但是无法通过<code>go build</code>和<code>go install</code>。命令源码文件并不一定必须放在 src 文件夹中，可以在任何目录以<code>go run</code>命令运行。</li>
<li>库源码文件<br>库源码文件是不具备命令源码文件上述两个特征的源码文件。存在于某个代码包中的普通源码文件。库源码文件被安装后，相应的归档文件（.a 文件）会被存放到当前工作区的<code>pkg</code>的平台相关目录下。</li>
<li>测试源码文件<br>名称以<code>_test.go</code>为后缀的代码文件，并且必须包含<code>Test</code>或者 <code>Benchmark</code>名称前缀的函数。名称以<code>Test</code>为名称前缀的函数，只能接受<code>*testing.T</code>的参数，这种测试函数是功能测试函数。名称以 <code>Benchmark</code>为名称前缀的函数，只能接受<code>*testing.B</code>的参数，这种测试函数是性能测试函数。</li>
</ul>
<h3 id="GOBIN"><a href="#GOBIN" class="headerlink" title="GOBIN"></a>GOBIN</h3><p> <code>GOBIN</code>是Go程序的可执行文件的目录。</p>
<h3 id="其它"><a href="#其它" class="headerlink" title="其它"></a>其它</h3><p>除了上述三个重要变量，可以使用<code>go env</code>查看其它的环境变量。<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">YDZ ~ $  go env</span><br><span class="line">GOARCH="amd64"</span><br><span class="line">GOBIN="/home/work/gocode/bin"</span><br><span class="line">GOEXE=""</span><br><span class="line">GOHOSTARCH="amd64"</span><br><span class="line">GOHOSTOS="linux"</span><br><span class="line">GOOS="linux"</span><br><span class="line">GOPATH="/home/work/gocode"</span><br><span class="line">GORACE=""</span><br><span class="line">GOROOT="/usr/local/go/1.8.3/libexec"</span><br><span class="line">GOTOOLDIR="/usr/local/go/1.8.3/libexec/pkg/tool/linux_amd64"</span><br><span class="line">GCCGO="gccgo"</span><br><span class="line">CC="clang"</span><br><span class="line">GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/66/dcf61ty92rgd_xftrsxgx5yr0000gn/T/go-build977187889=/tmp/go-build -gno-record-gcc-switches -fno-common"</span><br><span class="line">CXX="clang++"</span><br><span class="line">CGO_ENABLED="1"</span><br><span class="line">PKG_CONFIG="pkg-config"</span><br><span class="line">CGO_CFLAGS="-g -O2"</span><br><span class="line">CGO_CPPFLAGS=""</span><br><span class="line">CGO_CXXFLAGS="-g -O2"</span><br><span class="line">CGO_FFLAGS="-g -O2"</span><br><span class="line">CGO_LDFLAGS="-g -O2"</span><br></pre></td></tr></table></figure></p>
<table>
<thead>
<tr>
<th style="text-align:left">名称</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">CGO_ENABLED</td>
<td style="text-align:left">指明 cgo 工具是否可用的标识</td>
</tr>
<tr>
<td style="text-align:left">GOARCH</td>
<td style="text-align:left">程序构建环境的目标计算架构</td>
</tr>
<tr>
<td style="text-align:left">GOBIN</td>
<td style="text-align:left">存放可执行文件的目录的绝对路径</td>
</tr>
<tr>
<td style="text-align:left">GOCHAR</td>
<td style="text-align:left">程序构建环境的目标计算架构的单字符标识</td>
</tr>
<tr>
<td style="text-align:left">GOEXE</td>
<td style="text-align:left">可执行文件的后缀</td>
</tr>
<tr>
<td style="text-align:left">GOHOSTARCH</td>
<td style="text-align:left">程序运行环境的目标计算架构</td>
</tr>
<tr>
<td style="text-align:left">GOOS</td>
<td style="text-align:left">程序构建环境的目标操作系统</td>
</tr>
<tr>
<td style="text-align:left">GOHOSTOS</td>
<td style="text-align:left">程序运行环境的目标操作系统</td>
</tr>
<tr>
<td style="text-align:left">GOPATH</td>
<td style="text-align:left">工作区目录的绝对路径</td>
</tr>
<tr>
<td style="text-align:left">GORACE</td>
<td style="text-align:left">用于数据竞争检测的相关选项</td>
</tr>
<tr>
<td style="text-align:left">GOROOT</td>
<td style="text-align:left">Go 语言的安装目录的绝对路径</td>
</tr>
<tr>
<td style="text-align:left">GOTOOLDIR</td>
<td style="text-align:left">Go 工具目录的绝对路径</td>
</tr>
</tbody>
</table>
<h2 id="Go编译过程"><a href="#Go编译过程" class="headerlink" title="Go编译过程"></a>Go编译过程</h2><p><code>Go</code> 程序是通过 <code>package</code> 来组织的。<code>package &lt;pkgName&gt;</code>。包名 main 代表它是一个可独立运行的包，它在编译后会产生可执行文件。除了 main 包之外，其它的包最后都会生成 *.a 文件,并放置在<code>$GOPATH/pkg/$GOOS_$GOARCH</code>中。<code>Go</code>使用 <code>package</code>（和 <code>Python</code> 的模块类似）来组织代码。<code>main.main()</code> 函数是每一个独立的可运行程序的入口点。每一个可独立运行的 <code>Go</code> 程序，都包含一个 <code>package main</code>，在这个 <code>main</code> 包中包含一个入口函数 <code>main</code>，这个函数既没有参数，也没有返回值。<br><code>Go1.8</code>中基本命令有16个<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">build       compile packages and dependencies</span><br><span class="line">clean       remove object files</span><br><span class="line">doc         show documentation for package or symbol</span><br><span class="line">env         print Go environment information</span><br><span class="line">bug         start a bug report</span><br><span class="line">fix         run go tool fix on packages</span><br><span class="line">fmt         run gofmt on package sources</span><br><span class="line">generate    generate Go files by processing source</span><br><span class="line">get         download and install packages and dependencies</span><br><span class="line">install     compile and install packages and dependencies</span><br><span class="line">list        list packages</span><br><span class="line">run         compile and run Go program</span><br><span class="line">test        test packages</span><br><span class="line">tool        run specified go tool</span><br><span class="line">version     print Go version</span><br><span class="line">vet         run go tool vet on packages</span><br></pre></td></tr></table></figure></p>
<p>其中和编译相关的有<code>build</code>、<code>get</code>、<code>install</code>和<code>run</code>，重点介绍这4个命令。以下是通用的命令标记，都适用于这4个命令。</p>
<table>
<thead>
<tr>
<th style="text-align:left">名称</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">-a</td>
<td style="text-align:left">用于强制重新编译所有涉及的 Go 语言代码包（包括 Go 语言标准库中的代码包），即使它们已经是最新的了。该标记可以让我们有机会通过改动底层的代码包做一些实验。</td>
</tr>
<tr>
<td style="text-align:left">-n</td>
<td style="text-align:left">使命令仅打印其执行过程中用到的所有命令，而不去真正执行它们。如果不只想查看或者验证命令的执行过程，而不想改变任何东西，使用它正好合适。</td>
</tr>
<tr>
<td style="text-align:left">-race</td>
<td style="text-align:left">用于检测并报告指定 Go 语言程序中存在的数据竞争问题。当用 Go 语言编写并发程序的时候，这是很重要的检测手段之一。</td>
</tr>
<tr>
<td style="text-align:left">-v</td>
<td style="text-align:left">用于打印命令执行过程中涉及的代码包。这一定包括我们指定的目标代码包，并且有时还会包括该代码包直接或间接依赖的那些代码包。这会让你知道哪些代码包被执行过了。</td>
</tr>
<tr>
<td style="text-align:left">-work</td>
<td style="text-align:left">用于打印命令执行时生成和使用的临时工作目录的名字，且命令执行完成后不删除它。这个目录下的文件可能会对你有用，也可以从侧面了解命令的执行过程。如果不添加此标记，那么临时工作目录会在命令执行完毕前删除。</td>
</tr>
<tr>
<td style="text-align:left">-x</td>
<td style="text-align:left">使命令打印其执行过程中用到的所有命令，并同时执行它们。</td>
</tr>
</tbody>
</table>
<h3 id="go-run"><a href="#go-run" class="headerlink" title="go run"></a>go run</h3><p><code>go run</code> 命令只能接受一个命令源码文件以及若干个库源码文件（必须同属于<code>main</code>包）作为文件参数，且不能接受测试源码文件。它在执行时会检查源码文件的类型。如果参数中有多个或者没有命令源码文件，那么 <code>go run</code> 命令就只会打印错误提示信息并退出，而不会继续执行。<br>使用<code>-n</code>选项来看看<code>go run</code>做了些什么：<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">WORK ~/gocode/src/main $  go run -n helloworld.go</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span></span><br><span class="line"><span class="meta">#</span> command-line-arguments</span><br><span class="line"><span class="meta">#</span></span><br><span class="line"></span><br><span class="line">mkdir -p $WORK/command-line-arguments/_obj/</span><br><span class="line">mkdir -p $WORK/command-line-arguments/_obj/exe/</span><br><span class="line">cd /home/work/gocode/src/main</span><br><span class="line">/usr/local/go/1.8.3/libexec/pkg/tool/linux_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -complete -buildid 2841ae50ca62b7a3671974e64d76e198a2155ee7 -D _/home/work/gocode/src/me -I $WORK -pack ./helloworld.go</span><br><span class="line">cd .</span><br><span class="line">/usr/local/go/1.8.3/libexec/pkg/tool/llinux_amd64/link -o $WORK/command-line-arguments/_obj/exe/helloworld -L $WORK -w -extld=clang -buildmode=exe -buildid=2841ae50ca62b7a3671974e64d76e198a2155ee7 $WORK/command-line-arguments.a</span><br><span class="line"><span class="meta">$</span>WORK/command-line-arguments/_obj/exe/helloworld</span><br></pre></td></tr></table></figure></p>
<p><code>go run</code>命令创建了两个临时文件夹<code>_obj</code>和<code>_obj/exe</code>，然后<code>compile</code>再<code>link</code>生成了归档文件和可执行文件。<code>command-line-arguments</code> 归档文件是 Go 语言为命令源码文件临时指定的一个代码包。在接下来的几个命令中，生成的临时代码包都叫这个名字。<code>go run</code> 命令在第二次执行的时候，如果发现导入的代码包没有发生变化，不会再次编译这个导入的代码包。直接静态链接进来。为提高编译速度，可以加上-p n，n是并行的数量。n一般为逻辑 CPU 的个数。</p>
<h3 id="go-build"><a href="#go-build" class="headerlink" title="go build"></a>go build</h3><p>代码包中有且仅有一个命令源码文件时，在文件夹所在目录中执行 <code>go build</code> 命令，会在该目录下生成一个与目录同名的可执行文件。<code>go build</code> 用于编译指定的源码文件或代码包以及它们的依赖包，但是如果用来编译非命令源码文件（库源码文件），<code>go build</code> 执行完不会产生任何结果。这种情况下<code>go build</code> 命令只检查库源码文件的有效性，做检查性的编译，不会输出任何结果文件。<br>同样有<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">WORK ~/gocode/src/main $  go build -n helloworld.go</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span></span><br><span class="line"><span class="meta">#</span> command-line-arguments</span><br><span class="line"><span class="meta">#</span></span><br><span class="line"></span><br><span class="line">mkdir -p $WORK/command-line-arguments/_obj/</span><br><span class="line">mkdir -p $WORK/command-line-arguments/_obj/exe/</span><br><span class="line">cd /home/work/gocode/src/main</span><br><span class="line">/usr/local/go/1.8.3/libexec/pkg/tool/linux_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -complete -buildid 2841ae50ca62b7a3671974e64d76e198a2155ee7 -D _/home/work/gocode/src/me -I $WORK -pack ./helloworld.go</span><br><span class="line">cd .</span><br><span class="line">/usr/local/go/1.8.3/libexec/pkg/tool/llinux_amd64/link -o $WORK/command-line-arguments/_obj/exe/helloworld -L $WORK -w -extld=clang -buildmode=exe -buildid=2841ae50ca62b7a3671974e64d76e198a2155ee7 $WORK/command-line-arguments.a</span><br><span class="line">mv $WORK/command-line-arguments/_obj/exe/a.out helloworld</span><br></pre></td></tr></table></figure></p>
<p>执行过程和 <code>go run</code> 大体相同，不同在于最后一步，<code>go run</code> 执行了可执行文件，但是 <code>go build</code> 命令是把可执行文件移动到了当前目录的文件夹中。</p>
<h3 id="go-install"><a href="#go-install" class="headerlink" title="go install"></a>go install</h3><p><code>go install</code> 用于编译并安装指定的代码包及它们的依赖包。当指定的代码包的依赖包没有被编译和安装时，该命令会先去处理依赖包。与 <code>go build</code> 命令一样，传给 <code>go install</code> 命令的代码包参数应该以导入路径的形式提供。并且 <code>go build</code> 命令的绝大多数标记也都可以用于 <code>go install</code> 命令。实际上，<code>go install</code> 命令只比 <code>go build</code> 命令多做了一件事，安装编译后的结果文件到指定目录。安装代码包会在当前工作区的 <code>pkg</code> 的平台相关目录下生成归档文件（.a 文件）。安装命令源码文件会在当前工作区的 <code>bin</code> 目录（如果 <code>GOPATH</code> 下有多个工作区，就会放在 <code>GOBIN</code> 目录下）生成可执行文件。<br><code>go install</code> 命令后面如果跟了命令源码文件以及相关库源码文件作为参数的话，只有这些文件会被编译并安装。<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">WORK ~/gocode/src/main $  go install -n helloworld.go</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span></span><br><span class="line"><span class="meta">#</span> command-line-arguments</span><br><span class="line"><span class="meta">#</span></span><br><span class="line"></span><br><span class="line">mkdir -p $WORK/command-line-arguments/_obj/</span><br><span class="line">mkdir -p $WORK/command-line-arguments/_obj/exe/</span><br><span class="line">cd /home/work/gocode/src/main</span><br><span class="line">/usr/local/go/1.8.3/libexec/pkg/tool/linux_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -complete -buildid 2841ae50ca62b7a3671974e64d76e198a2155ee7 -D _/home/work/gocode/src/me -I $WORK -pack ./helloworld.go</span><br><span class="line">cd .</span><br><span class="line">/usr/local/go/1.8.3/libexec/pkg/tool/llinux_amd64/link -o $WORK/command-line-arguments/_obj/exe/helloworld -L $WORK -w -extld=clang -buildmode=exe -buildid=2841ae50ca62b7a3671974e64d76e198a2155ee7 $WORK/command-line-arguments.a</span><br><span class="line">mkdir -p /home/work/gocode/bin/</span><br><span class="line">mv $WORK/command-line-arguments/_obj/exe/a.out /home/work/gocode/bin/helloworld</span><br></pre></td></tr></table></figure></p>
<p>在安装多个库源码文件时有可能遇到如下的问题：<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hc@ubt:~/golang/goc2p/src/pkgtool$ go install envir.go fpath.go ipath.go pnode.go util.go</span><br><span class="line">go install: no install location for .go files listed on command line (GOBIN not set)</span><br></pre></td></tr></table></figure></p>
<p>在为环境变量 <code>GOBIN</code> 设置了正确的值之后，这个错误提示信息仍然会出现。这是因为只有在安装命令源码文件时，命令程序才会将环境变量 <code>GOBIN</code> 的值作为结果文件的存放目录。而在安装库源码文件时，在命令程序内部的代表结果文件存放目录路径的那个变量不会被赋值。最后命令程序会发现它依然是个无效的空值,所以命令程序会同样返回一个关于“无安装位置”的错误。这就引出一个结论，我们只能使用安装代码包的方式来安装库源码文件，而不能在 <code>go install</code> 命令罗列并安装它们。另外，<code>go install</code> 命令目前无法接受标记<code>-o</code>以自定义结果文件的存放位置。这也从侧面说明了<code>go install</code> 命令不支持针对库源码文件的安装操作。</p>
<h3 id="go-get"><a href="#go-get" class="headerlink" title="go get"></a>go get</h3><p><code>go get</code> 命令用于从远程代码仓库（比如 <code>Github</code> ）上下载并安装代码包。，<code>go get</code> 命令会把当前的代码包下载到 <code>$GOPATH</code> 中的第一个工作区的 <code>src</code> 目录（而非vendor目录）中并安装。<br>在 <code>go get</code> 下载过程中加入<code>-d</code> 标记，下载操作只会执行下载动作而不执行安装动作。有些非常特殊的代码包在安装过程中需要有特殊的处理，所以我们需要先下载下来，所以就会用到<code>-d</code> 标记。<br>还有一个很有用的标记是<code>-u</code>标记，加上它可以利用网络来更新已有的代码包及其依赖包。如果已经下载过一个代码包，但是这个代码包又有更新了，那么这时候可以直接用<code>-u</code>标记来更新本地的对应的代码包。如果不加这个<code>-u</code>标记，执行 <code>go get</code> 一个已有的代码包，会发现命令什么都不执行。只有加了<code>-u</code>标记，命令会去执行 <code>git pull</code> 命令拉取最新的代码包的最新版本，下载并安装。<br>命令 <code>go get</code> 还有一个很值得称道的功能——智能下载。在使用它检出或更新代码包之后，它会寻找与本地已安装 Go 语言的版本号相对应的标签（<code>tag</code>）或分支（<code>branch</code>）。比如，本机安装 Go 语言的版本是1.x，那么 <code>go get</code> 命令会在该代码包的远程仓库中寻找名为 “go1” 的标签或者分支。如果找到指定的标签或者分支，则将本地代码包的版本切换到此标签或者分支。如果没有找到指定的标签或者分支，则将本地代码包的版本切换到主干的最新版本。</p>
<table>
<thead>
<tr>
<th style="text-align:left">名称</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">-d</td>
<td style="text-align:left">让命令程序只执行下载动作，而不执行安装动作。</td>
</tr>
<tr>
<td style="text-align:left">-f</td>
<td style="text-align:left">仅在使用-u标记时才有效。该标记会让命令程序忽略掉对已下载代码包的导入路径的检查。如果下载并安装的代码包所属的项目是你从别人那里 Fork 过来的，那么这样做就尤为重要了。</td>
</tr>
<tr>
<td style="text-align:left">-fix</td>
<td style="text-align:left">让命令程序在下载代码包后先执行修正动作，而后再进行编译和安装。</td>
</tr>
<tr>
<td style="text-align:left">-insecure</td>
<td style="text-align:left">允许命令程序使用非安全的 scheme（如 HTTP ）去下载指定的代码包。如果你用的代码仓库（如公司内部的 Gitlab ）没有HTTPS 支持，可以添加此标记。请在确定安全的情况下使用它。</td>
</tr>
<tr>
<td style="text-align:left">-t</td>
<td style="text-align:left">让命令程序同时下载并安装指定的代码包中的测试源码文件中依赖的代码包。</td>
</tr>
<tr>
<td style="text-align:left">-u</td>
<td style="text-align:left">让命令利用网络来更新已有代码包及其依赖包。默认情况下，该命令只会从网络上下载本地不存在的代码包，而不会更新已有的代码包。</td>
</tr>
</tbody>
</table>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">cd .</span><br><span class="line">git clone https://github.com/go-errors/errors /home/work/gocode/src/github.com/go-errors/errors</span><br><span class="line">cd /home/work/gocode/src/github.com/go-errors/errors</span><br><span class="line">git submodule update --init --recursive</span><br><span class="line">cd /home/work/gocode/src/github.com/go-errors/errors</span><br><span class="line">git show-ref</span><br><span class="line">cd /home/work/gocode/src/github.com/go-errors/errors</span><br><span class="line">git submodule update --init --recursive</span><br><span class="line">WORK=/var/folders/66/dcf61ty92rgd_xftrsxgx5yr0000gn/T/go-build124856678</span><br><span class="line">mkdir -p $WORK/github.com/go-errors/errors/_obj/</span><br><span class="line">mkdir -p $WORK/github.com/go-errors/</span><br><span class="line">cd /home/work/gocode/src/github.com/go-errors/errors</span><br><span class="line">/usr/local/Cellar/go/1.8.3/libexec/pkg/tool/linux_amd64/compile -o $WORK/github.com/go-errors/errors.a -trimpath $WORK -p github.com/go-errors/errors -complete -buildid bb3526a8c1c21853f852838637d531b9fcd57d30 -D _/home/work/gocode/src/github.com/go-errors/errors -I $WORK -pack ./error.go ./parse_panic.go ./stackframe.go</span><br><span class="line">mkdir -p /home/work/gocode/pkg/linux_amd64/github.com/go-errors/</span><br><span class="line">mv $WORK/github.com/go-errors/errors.a /home/work/gocode/pkg/linux_amd64/github.com/go-errors/errors.a</span><br></pre></td></tr></table></figure>
<p>执行完 <code>go get</code> 命令以后，会调用 <code>git clone</code> 方法下载源码并编译，最终会把库源码文件编译成归档文件安装到 <code>pkg</code> 对应的相关平台目录下。<br>一般情况下，为了分离自己与第三方的代码，我们会设置两个或更多的工作区。我们现在有一个目录路径为 <code>/home/work/golang/lib</code> 的工作区，并且它是环境变量 <code>GOPATH</code> 值中的第一个目录路径。注意，环境变量 <code>GOPATH</code> 中包含的路径不能与环境变量GOROOT的值重复。如果我们使用 <code>go get</code> 命令下载和安装代码包，那么这些代码包都会被安装在上面这个工作区中。我们暂且把这个工作区叫做 <code>Lib</code> 工作区。</p>
<h2 id="Static-Dynamic-Link"><a href="#Static-Dynamic-Link" class="headerlink" title="Static | Dynamic Link"></a>Static | Dynamic Link</h2><p>在 <code>go build</code> 、<code>go install</code> 的时候加上 <code>-buildmode</code> 参数。<br>这些是以下 <code>buildmode</code> 的选项：<br><code>archive</code>: 将非 <code>main</code> 包构建为 <code>.a</code>文件 <code>.main</code> 包将被忽略。<br><code>c-archive</code>: 将 <code>main</code> 软件包及其导入的所有软件包构建到 C 归档文件中<br><code>c-shared</code>: 将列出的主要软件包，以及它们导入的所有软件包构建到 C 动态库中。<br><code>shared</code>: 将所有列出的非 <code>main</code> 软件包合并到一个动态库中。<br><code>exe</code>: 构建列出的 <code>main</code> 包及其导入到可执行文件中的一切。 将忽略未命名为 <code>main</code> 的包。<br>默认情况下，列出的 <code>main</code> 软件包内置到可执行文件中，列出的非 <code>main</code> 软件包内置到 <code>.a</code> 文件中。</p>

      
    </div>

    

    
    
    

    

    
      
    
    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Go/" rel="tag"># Go</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/09/01/jottings/Take me hand/" rel="next" title="Take me hand">
                <i class="fa fa-chevron-left"></i> Take me hand
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/09/09/tech/微服务架构概念解读/" rel="prev" title="微服务架构概念解读">
                微服务架构概念解读 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>


  </div>


          </div>
          

  
    <div class="comments" id="comments">
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image" src="/images/logo1.jpg" alt="方林">
            
              <p class="site-author-name" itemprop="name">方林</p>
              <div class="site-description motion-element" itemprop="description">愿你出走半生，归来仍是少年</div>
          </div>

          
            <nav class="site-state motion-element">
              
                <div class="site-state-item site-state-posts">
                
                  <a href="/archives/">
                
                    <span class="site-state-item-count">27</span>
                    <span class="site-state-item-name">日志</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-categories">
                  
                    
                      <a href="/categories/">
                    
                  
                    
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">3</span>
                    <span class="site-state-item-name">分类</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-tags">
                  
                    
                      <a href="/tags/">
                    
                  
                    
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">17</span>
                    <span class="site-state-item-name">标签</span>
                  </a>
                </div>
              
            </nav>
          

          
            <div class="feed-link motion-element">
              <a href="/atom.xml" rel="alternate">
                <i class="fa fa-rss"></i>
                RSS
              </a>
            </div>
          

          

          
            <div class="links-of-author motion-element">
              
                <span class="links-of-author-item">
                  
                  
                    
                  
                  
                    
                  
                  <a href="https://github.com/yourname" title="GitHub &rarr; https://github.com/yourname" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i>GitHub</a>
                </span>
              
                <span class="links-of-author-item">
                  
                  
                    
                  
                  
                    
                  
                  <a href="mailto:sean_ps@163.com" title="E-Mail &rarr; mailto:sean_ps@163.com" rel="noopener" target="_blank"><i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                </span>
              
            </div>
          

          

          
          
            <div class="links-of-blogroll motion-element links-of-blogroll-block">
              <div class="links-of-blogroll-title">
                <i class="fa  fa-fw fa-link"></i>
                Links
              </div>
              <ul class="links-of-blogroll-list">
                
                  <li class="links-of-blogroll-item">
                    <a href="http://www.luoo.net" title="http://www.luoo.net" rel="noopener" target="_blank">落网</a>
                  </li>
                
              </ul>
            </div>
          

          
            
          
          

        </div>
      </div>

      
      <!--noindex-->
        <div class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
            
            
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#环境变量"><span class="nav-number">1.</span> <span class="nav-text">环境变量</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#GOROOT"><span class="nav-number">1.1.</span> <span class="nav-text">GOROOT</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#GOPATH"><span class="nav-number">1.2.</span> <span class="nav-text">GOPATH</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#GOBIN"><span class="nav-number">1.3.</span> <span class="nav-text">GOBIN</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#其它"><span class="nav-number">1.4.</span> <span class="nav-text">其它</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Go编译过程"><span class="nav-number">2.</span> <span class="nav-text">Go编译过程</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#go-run"><span class="nav-number">2.1.</span> <span class="nav-text">go run</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#go-build"><span class="nav-number">2.2.</span> <span class="nav-text">go build</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#go-install"><span class="nav-number">2.3.</span> <span class="nav-text">go install</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#go-get"><span class="nav-number">2.4.</span> <span class="nav-text">go get</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Static-Dynamic-Link"><span class="nav-number">3.</span> <span class="nav-text">Static | Dynamic Link</span></a></li></ol></div>
            

          </div>
        </div>
      <!--/noindex-->
      

      

    </div>
  </aside>
  


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2019</span>
  <span class="with-love" id="animate">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">fanglin</span>

  

  
</div>









        








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

    

    
  </div>

  

<script>
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>


























  
  <script src="/lib/jquery/index.js?v=2.1.3"></script>

  
  <script src="/lib/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>


  


  <script src="/js/utils.js?v=7.1.0"></script>

  <script src="/js/motion.js?v=7.1.0"></script>



  
  


  <script src="/js/affix.js?v=7.1.0"></script>

  <script src="/js/schemes/pisces.js?v=7.1.0"></script>



  
  <script src="/js/scrollspy.js?v=7.1.0"></script>
<script src="/js/post-details.js?v=7.1.0"></script>



  


  <script src="/js/next-boot.js?v=7.1.0"></script>


  

  

  

  
  

<script src="//cdn1.lncld.net/static/js/3.11.1/av-min.js"></script>



<script src="//unpkg.com/valine/dist/Valine.min.js"></script>

<script>
  var GUEST = ['nick', 'mail', 'link'];
  var guest = 'nick,mail,link';
  guest = guest.split(',').filter(function(item) {
    return GUEST.indexOf(item) > -1;
  });
  new Valine({
    el: '#comments',
    verify: true,
    notify: false,
    appId: 'jjdDCzDO6jlN5yOgAbnVwdJ3-gzGzoHsz',
    appKey: 'jnjP7aorboCG7pJV6HvdMP15',
    placeholder: 'ヾﾉ≧∀≦)o来啊，快活啊!',
    avatar: 'mm',
    meta: guest,
    pageSize: '10' || 10,
    visitor: false,
    lang: 'zh-cn' || 'zh-cn'
  });
</script>




  


  




  

  

  

  

  

  

  

  

  

  

  

  

  

  

</body>
</html>
